package com.mediacloud.app.newsmodule.fragment.navlive

import android.view.View
import android.widget.TextView
import com.mediacloud.app.assembly.util.toastCenter
import com.mediacloud.app.model.eventbus.event.LoginEvent
import com.mediacloud.app.model.fragment.BaseFragment
import com.mediacloud.app.model.interfaces.DataInvokeCallBack
import com.mediacloud.app.model.news.ArticleItem
import com.mediacloud.app.model.news.LiveProgramListReciver
import com.mediacloud.app.model.news.ProgramListItem
import com.mediacloud.app.model.utils.ViewUtils
import com.mediacloud.app.newsmodule.R
import com.mediacloud.app.newsmodule.utils.AppointmentController
import com.mediacloud.app.newsmodule.utils.VideoLiveProgramListInvoker
import com.mediacloud.app.reslib.util.DataInvokeUtil
import com.mediacloud.app.user.model.UserInfo
import com.mediacloud.app.user.utils.RxUtils
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.navigate_liveprogram.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.jetbrains.anko.collections.forEachWithIndex
import org.json.JSONObject
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.collections.ArrayList

/**
 * 直播节目单
 */
class NavigateLiveProgramFragment : BaseFragment() {
    companion object {
        const val VideoID: String = "VideoId"
        const val Item: String = "ArticleItem"
        const val Date: String = "Date"
        const val ContentID: String = "ContentID"
        const val ChannelName: String = "ChannelName"
    }

    private var programList: androidx.recyclerview.widget.RecyclerView? = null
    private var noProgram: TextView? = null
    private var adapter: NavLiveProgramListAdapter? = null
    private var chooseIndexMap: MutableMap<String, Int> = HashMap()
    var needScrollToPosition = false
    var contentID: String? = null
    var channelName: String? = null
    var isFirstPlay = true
    var isClick = false
    var  appointmentController : AppointmentController ?= null
    var currentItem:ProgramListItem ?= null
    var currentPosition:Int = 0

    override fun getLayoutResID(): Int {
        return R.layout.navigate_liveprogram
    }

    override fun initView() {
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
        programList = findViewById(R.id.programList)
        noProgram = findViewById(R.id.noProgram)
        programList?.layoutManager = ViewUtils.generateRecyclerLinearLayoutManager(activity, true)
        adapter = NavLiveProgramListAdapter(activity)
        programList?.adapter = adapter

        appointmentController  = AppointmentController(requireContext(), object : AppointmentController.AppointmentStatusListener {
            override fun onAppointmentStatus(contentId: String?, appointmented: Boolean) {

            }

            override fun onAppointmentOk(contentId: String?, appointmented: Boolean, count:Long) {
                isClick = false
                currentItem?.isAppointment = appointmented
                adapter?.notifyItemChanged(currentPosition)
            }

            override fun onAppointmentErr(msg: String?) {
                isClick = false
            }

        })
        adapter!!.setItemClickListener { index, _, _ ->
                val item = adapter!!.getItem(index)
                val state = ProgramListItem.getItemState(item)
                val handleReplay = NavigateLiveFragment::handleReplay
                if (state == ProgramListItem.GuideItemState.REPLAY || state == ProgramListItem.GuideItemState.LIVE) {
                   //getInstance().watch_live_tvshow(item.channelid,item.name,item.name)
                    //回看
                    if (index != adapter!!.chooseIndex) {
                        isFirstPlay = false
                        adapter!!.chooseIndex = index
                        val key = currentDate!!
                        chooseIndexMap[key] = index
                        if (parentFragment != null && parentFragment is NavigateLiveFragment) {
                            handleReplay(
                                parentFragment as NavigateLiveFragment,
                                item
                            )
                        }
                    }
                    adapter?.notifyDataSetChanged()
                } else if (state == ProgramListItem.GuideItemState.APPOINTMENTED||state == ProgramListItem.GuideItemState.COMING_SOON) {
                    if (isClick) return@setItemClickListener
                   // cancelAppointment(item, index)
                    currentItem = item
                    currentPosition = index
                    isClick = true
                    appointmentController?.Appointment(contentID,channelName,3,item.starttime, item.endtime,"${item.id}")

                } //else if (state == ProgramListItem.GuideItemState.COMING_SOON) {

//                    if (!UserInfo.isLogin(context)) {
//                        LoginUtils.invokeLogin(activity, Intent(), LoginUtils.INVOKE_LOGIN)
//                        return@setItemClickListener
//                    }
//                    val startTime =
//                        DateParse.parseDate(item.getStarttime(), null).time
//                    val nowTime = Date(System.currentTimeMillis()).time
//                    val pushAppointmentTime =
//                        AppFactoryGlobalConfig.getAppServerConfigInfo(context).otherFunction.push_appointment_time
//                    if (startTime - nowTime < pushAppointmentTime * 60 * 1000) {//小于十分钟
//                        var view = LayoutInflater.from(context).inflate(R.layout.toast_view, null)
//                        view.findViewById<TextView>(R.id.tv_content).text =
//                            "精彩内容即将开始\n距离直播开始${pushAppointmentTime}分钟内\n无法预约"
//                        toastCenter(requireActivity(), view)
//                    } else {
//                        if (isClick) return@setItemClickListener
//                        appointment(item, index)
//                    }

//            else if(state==ProgramListItem.GuideItemState.LIVE&&adapter!!.chooseIndex!=-1)//跳回直播
//            {
//                adapter!!.chooseIndex=-1
//                if(parentFragment!=null && parentFragment is NavigateLiveFragment)
//                {
//                    handleReplay(parentFragment as NavigateLiveFragment,adapter!!.getItem(index))
//                }
//            }


            }
      //  }
    }

    /**
     * 预约
     */
    private fun appointment(item: ProgramListItem, index: Int) {
        isClick = true
        progressBar.visibility = View.VISIBLE
        val map = mutableMapOf<String, Any>()
        map["user_id"] = UserInfo.userinfo.userid
        channelName?.let {
            map["title"] = it
        }
        map["type"] = 3
        contentID?.let { map["content_id"] = it }
        map["start_time"] = item.starttime
        map["end_time"] = item.endtime
        map["playbill_id"] = item.id
        map["name"] = item.name
        DataInvokeUtil.getZiMeiTiApi()
            .appointment(map)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<JSONObject> {
                override fun onSubscribe(d: Disposable) {}
                override fun onError(e: Throwable) {}
                override fun onComplete() {}
                override fun onNext(t: JSONObject) {
                    progressBar.visibility = View.GONE
                    isClick = false
                    if (t.optBoolean("state")) {
                        item.isAppointment = true
                        toastCenter(requireActivity(), "预约成功")
                        adapter!!.notifyItemChanged(index)
                        val data: JSONObject = t.optJSONObject("data")
                        data?.let {
                            val id = it.optInt("id")
                            item.appointmentId = id
                        }

                    } else {
                        toastCenter(requireActivity(), "网络异常，请检查网络")
                    }
                }
            })

    }

    /**
     * 取消预约
     */
    private fun cancelAppointment(item: ProgramListItem, index: Int) {
        progressBar.visibility = View.VISIBLE
        isClick = true
        val map = mutableMapOf<String, Any>()
        map["id"] = item.appointmentId
        DataInvokeUtil.getZiMeiTiApi()
            .cancelAppointment(map)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<JSONObject> {
                override fun onSubscribe(d: Disposable) {}
                override fun onError(e: Throwable) {}
                override fun onComplete() {}
                override fun onNext(t: JSONObject) {
                    progressBar.visibility = View.GONE
                    isClick = false
                    if (t.optBoolean("state")) {
                        item.isAppointment = false
                        toastCenter(requireActivity(), "取消预约成功")
                        adapter!!.notifyItemChanged(index)
                    } else {
                        toastCenter(requireActivity(), "网络异常，请检查网络")
                    }
                }
            })

    }


    override fun initOther() {
        super.initOther()
        val videoId = fragmentArguments.getString(VideoID)
        val date = fragmentArguments.getString(Date)
        val item = fragmentArguments.getParcelable<ArticleItem>(Item)
        contentID = fragmentArguments.getString(ContentID)
        channelName = fragmentArguments.getString(ChannelName)
        if (videoId?.isEmpty() == false && date?.isEmpty() == false) {
            updateDate(item!!,videoId, date, false, contentID, channelName)
        } else {
            setNoProgramListVisible(View.VISIBLE)
        }
       // getInstance().view_tvshow_page(contentID, channelName, channelName)
    }

    private var programListInvoker: VideoLiveProgramListInvoker? = null

    var currentDate: String? = null

    @JvmOverloads
    fun updateDate(
        item: ArticleItem,
        videoId: String, date: String, isChangeChannel: Boolean = false, contentID: String?,
        channelName: String?, playTime: Long = 0L,
    ) {
        this.contentID = contentID
        this.channelName = channelName
        this.videoId = videoId
        this.date = date
        this.item = item
//        if (UserInfo.isLogin(context)) {
//            getAppointmentList(contentID)
//        }
        needScrollToPosition = false
        currentDate = videoId.plus(date)
        programListInvoker?.destory()
        val key = currentDate!!
        if (isChangeChannel) {
            adapter!!.chooseIndex = -1
            chooseIndexMap.clear()
            chooseIndexMap[key] = -1
        } else if (chooseIndexMap.containsKey(key) && chooseIndexMap[key]!! > -1) {
            adapter!!.chooseIndex = chooseIndexMap[key]!!
        } else {
            chooseIndexMap[key] = -1
            adapter!!.chooseIndex = -1
        }
        adapter?.data?.clear()
        adapter?.notifyDataSetChanged()
        clearTimer()
        programListInvoker =
            VideoLiveProgramListInvoker(object : DataInvokeCallBack<LiveProgramListReciver> {
                override fun fault(data: Any?) {
                    println(data)
                    setNoProgramListVisible(View.VISIBLE)
                }

                var findLive = { index: Int, item: ProgramListItem ->
                    if (adapter!!.chooseIndex == -1) {
                        val guideItemState = ProgramListItem.getItemState(item)
                        if (guideItemState == ProgramListItem.GuideItemState.LIVE) {
//                        if (MMKV.defaultMMKV().decodeBool(XKey.AUTO_PLAY, false)) {
//                            adapter!!.chooseIndex = index
//                            programList?.scrollToPosition(index)
//                        } else {
//                            adapter!!.livingIndex = index
//
//                        }
                            adapter!!.livingIndex = index
                            programList?.scrollToPosition(index)
                        }
                    } else if (index == adapter!!.chooseIndex) {
                        programList?.scrollToPosition(index)
                    }

                }

                override fun success(data: LiveProgramListReciver) {
                    if (data.state && data.programListItems?.size!! > 0) {

                        for (i in data.programListItems.indices) {
                            if (date == data.programListItems[i].date) {
                                if (data.programListItems[i].programList.size == 0) {
                                    setNoProgramListVisible(View.VISIBLE)
                                } else {
                                    val temp = data.programListItems[i].programList
                                    temp.forEach {
                                        if (appointmentMap.containsKey(it.id)) {
                                            it.isAppointment = true
                                            it.appointmentId = appointmentMap[it.id]!!
                                        } else {
                                            it.isAppointment = false
                                        }
                                    }
                                    adapter!!.data.addAll(temp)
                                    if (playTime != 0L) {
                                        var tempPosition = 0
                                        for (k in temp.indices) {
                                            val t = temp[k]
                                            if (t.startLong < playTime) {
                                                tempPosition = k
                                                needScrollToPosition = true
                                            } else {
                                                break
                                            }
                                        }
                                        adapter!!.chooseIndex = tempPosition
                                    }
                                    adapter!!.notifyDataSetChanged()
                                    adapter!!.data.forEachWithIndex(findLive)
                                    timerUpdateProgramList()
                                    setNoProgramListVisible(View.GONE)
                                }

                            }
                        }
                        val allList: MutableList<ProgramListItem> = ArrayList()
                        data.programListItems?.forEach {
                            allList.addAll(it.programList)
                        }
                        val tempParentFragment = parentFragment
                        if (tempParentFragment is NavigateLiveFragment) {
                            tempParentFragment.setPrograms(allList)
                        }
                    } else {
                        setNoProgramListVisible(View.VISIBLE)
                    }
                }
            })
        programListInvoker?.getLiveVideoProgramList(item, date)
    }

    var appointmentMap = mutableMapOf<Int, Int>()//key:节目单id,value:预约id
    private fun getAppointmentList(contentID: String?) {

        appointmentMap.clear()
        DataInvokeUtil.getZiMeiTiApi()
            .getAppointmentList(UserInfo.getUserInfo(context).userid, 1, contentID, 1, 50)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<JSONObject> {
                override fun onSubscribe(d: Disposable) {}
                override fun onError(e: Throwable) {}
                override fun onComplete() {}
                override fun onNext(t: JSONObject) {
                    if (t.optBoolean("state")) {
                        t.optJSONObject("data")?.let {
                            val meta = it.optJSONArray("meta")
                            meta?.let { meta ->
                                for (index in 0 until meta.length()) {
                                    val playBillid =
                                        meta.getJSONObject(index).optInt("playbill_id")//节目单id
                                    val id = meta.getJSONObject(index).optInt("id")//预约id
                                    appointmentMap[playBillid] = id
                                }
                            }


                        }
                    }
                }
            })

    }

    private fun setNoProgramListVisible(value: Int) {
        noProgram?.visibility = value
    }

    override fun onDestroy() {
        super.onDestroy()
        //getInstance().quit_play_live_tvshow(contentID, channelName, channelName)
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
        programListInvoker?.destory()
        adapter?.data?.clear()
        clearTimer()
    }

    private val interval = 10L
    private var disposeAble: Disposable? = null
    private fun timerUpdateProgramList() {
        clearTimer()
        disposeAble = Observable.interval(0L, interval, TimeUnit.SECONDS)
            .compose(RxUtils.schedulersTransformer()).subscribe {
            adapter?.notifyDataSetChanged()
        }
    }

    private fun clearTimer() {
        if (disposeAble?.isDisposed == false)
            disposeAble?.dispose()
    }

    fun scrollToPosition() {
        if (needScrollToPosition) {
            needScrollToPosition = false
            programList?.postDelayed({ programList?.scrollToPosition(adapter!!.chooseIndex) }, 400)
        }
    }

    var videoId: String = ""
    var date: String = ""
    var item:ArticleItem ?= null

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun loginState(loginEvent: LoginEvent?) {
        if (UserInfo.isLogin(context)) //登录刷新列表
            updateDate(item!!,videoId, date, false, contentID, channelName)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun update(data: JSONObject) {  //我的预约改变状态刷新列表
        updateDate(item!!,videoId, date, false, contentID, channelName)
    }

    fun setPlay() {
        if (!isFirstPlay) return
        isFirstPlay = false
        if (adapter?.livingIndex != -1) {
            adapter?.chooseIndex = adapter!!.livingIndex
            adapter?.livingIndex = -1
            adapter?.notifyDataSetChanged()

            adapter?.let {
                if (it.getItem(it.chooseIndex)!= null){
                    val kFunction2 = NavigateLiveFragment::handleReplay
                    val item: ProgramListItem = it.getItem(it.chooseIndex)
                    if (parentFragment != null && parentFragment is NavigateLiveFragment){
                        kFunction2(parentFragment as NavigateLiveFragment,item)
                    }
                }

            }

        }
    }

    fun freshAdapter(item2: ProgramListItem) {
        adapter?.let {
            for (i in it.data.indices){
                if (it.data[i].id == item2.id){
                    it.chooseIndex = i
                    val key = currentDate!!
                    chooseIndexMap[key] = i
                    break
                }
            }
            it.notifyDataSetChanged()
        }
        needScrollToPosition = true
        scrollToPosition()
    }
}